home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / devices / msh_1_5 / part01 / src / messyfmt.c < prev    next >
C/C++ Source or Header  |  1990-02-21  |  9KB  |  343 lines

  1. /*
  2.  * MESSYFMT.C
  3.  *
  4.  * Formats a disk. Low-level formatting can also be done by mounting a file
  5.  * system and using the AmigaDOS format command.
  6.  *
  7.  * This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
  8.  * May not be used or copied without a licence.
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include "han.h"
  13. extern int    Enable_Abort;
  14.  
  15. ulong        BootBlock[] = {
  16.     0xEB349049, 0x424D2020, 0x332E3200, 0x02020100,    /* ...IBM  3.2..... */
  17.     0x027000A0, 0x05F90300, 0x09000200, 0x00000000,
  18.     0x00000000, 0x00000000, 0x00000000, 0x0000000F,
  19.     0x00000000, 0x0100FA33, 0xC08ED0BC, 0x007C1607,
  20.     0xBB780036, 0xC5371E56, 0x1653BF2B, 0x7CB90B00,
  21.     0xFCAC2680, 0x3D007403, 0x268A05AA, 0x8AC4E2F1,
  22.     0x061F8947, 0x02C7072B, 0x7CFBCD13, 0x7267A010,
  23.     0x7C98F726, 0x167C0306, 0x1C7C0306, 0x0E7CA33F,
  24.     0x7CA3377C, 0xB82000F7, 0x26117C8B, 0x1E0B7C03,
  25.     0xC348F7F3, 0x0106377C, 0xBB0005A1, 0x3F7CE896,
  26.     0x00B80102, 0xE8AA0072, 0x198BFBB9, 0x0B00BECD,
  27.     0x7DF3A675, 0x0D8D7F20, 0xBED87DB9, 0x0B00F3A6,
  28.     0x7418BE6E, 0x7DE86100, 0x32E4CD16, 0x5E1F8F04,
  29.     0x8F4402CD, 0x19BEB77D, 0xEBEBA11C, 0x0533D2F7,
  30.     0x360B7CFE, 0xC0A23C7C, 0xA1377CA3, 0x3D7CBB00,
  31.     0x07A1377C, 0xE84000A1, 0x187C2A06, 0x3B7C4050,
  32.     0xE84E0058, 0x72CF2806, 0x3C7C760C, 0x0106377C,
  33.     0xF7260B7C, 0x03D8EBD9, 0x8A2E157C, 0x8A16FD7D,
  34.     0x8B1E3D7C, 0xEA000070, 0x00AC0AC0, 0x7422B40E,
  35.     0xBB0700CD, 0x10EBF233, 0xD2F73618, 0x7CFEC288,
  36.     0x163B7C33, 0xD2F7361A, 0x7C88162A, 0x7CA3397C,
  37.     0xC3B4028B, 0x16397CB1, 0x06D2E60A, 0x363B7C8B,
  38.     0xCA86E98A, 0x16FD7D8A, 0x362A7CCD, 0x13C30D0A,
  39.     0x4E6F6E2D, 0x53797374, 0x656D2064, 0x69736B20,    /* Non-System disk  */
  40.     0x6F722064, 0x69736B20, 0x6572726F, 0x720D0A52,    /* or disk error..R */
  41.     0x65706C61, 0x63652061, 0x6E642073, 0x7472696B,    /* eplace and strik */
  42.     0x6520616E, 0x79206B65, 0x79207768, 0x656E2072,    /* e any key when r */
  43.     0x65616479, 0x0D0A000D, 0x0A446973, 0x6B20426F,    /* eady.....Disk Bo */
  44.     0x6F742066, 0x61696C75, 0x72650D0A, 0x0049424D,    /* ot failure...IBM */
  45.     0x42494F20, 0x20434F4D, 0x49424D44, 0x4F532020,    /* BIO    COMIBMDOS   */
  46.     0x434F4D00, 0x00000000, 0x00000000, 0x00000000,    /* COM............. */
  47.     0x00000000, 0x00000000, 0x00000000, 0x000055AA,
  48. };
  49.  
  50. byte           *DiskTrack;
  51. long        TrackSize;
  52. int        Track;
  53. int        LowTrack;
  54. word        nsides;
  55. struct IOExtTD *TDReq,
  56.            *CreateExtIO();
  57. char           *Device;
  58.  
  59. int
  60. todigit(c)
  61. register char    c;
  62. {
  63.     if ((c -= '0') < 0 || c > ('F' - '0'))
  64.     return 42;
  65.  
  66.     if (c >= ('A' - '0')) {
  67.     c -= 'A' - '9' - 1;
  68.     }
  69.     return c;
  70. }
  71.  
  72. long
  73. ntoi(str)
  74. register char  *str;
  75. {
  76.     register long   total = 0;
  77.     register long   value;
  78.     register int    digit;
  79.     register int    base;
  80.  
  81.     /* First determine the base */
  82. number:
  83.     if (*str == '0') {
  84.     if (*++str == 'x') {    /* 0x means hexadecimal */
  85.         base = 16;
  86.         str++;
  87.     } else {
  88.         base = 8;        /* Otherwise, 0 means octal */
  89.     }
  90.     } else {
  91.     base = 10;        /* and any other digit means decimal */
  92.     }
  93.  
  94.     value = 0;
  95.     while ((digit = todigit(*str)) < base) {
  96.     value *= base;
  97.     value += digit;
  98.     str++;
  99.     }
  100.  
  101. suffix:
  102.     switch (*str++) {
  103.     case 'm':                   /* scale with megabytes */
  104.     value *= 1024L * 1024;
  105.     goto suffix;
  106.     case 'k':                   /* scale with kilobytes */
  107.     value *= 1024;
  108.     goto suffix;
  109.     case 's':                   /* scale with sectors */
  110.     value *= TD_SECTOR;    /* or maybe even kilosectors! */
  111.     goto suffix;
  112.     case 'b':                   /* scale with bytes */
  113.     goto suffix;
  114.     }
  115.     str--;
  116.  
  117.     total += value;
  118.  
  119.     if (*str >= '0' && *str <= '9')
  120.     goto number;        /* Allow 10k512, recursion eliminated */
  121.  
  122.     return total;
  123. }
  124.  
  125. word
  126. input(question, defval)
  127. char           *question;
  128. word        defval;
  129. {
  130.     char        buf[80];
  131.  
  132.     printf("%s? [%d] ", question, defval);
  133.     fflush(stdout);
  134.     if (fgets(buf, sizeof (buf) - 1, stdin)) {
  135.     if (buf[0] && buf[0] != '\n')
  136.         defval = ntoi(buf);
  137.     }
  138.     return defval;
  139. }
  140.  
  141. void
  142. PutWord(address, value)
  143. register byte  *address;
  144. register word    value;
  145. {
  146.     address[0] = value;
  147.     address[1] = value >> 8;
  148. }
  149.  
  150. word
  151. SetWord(address, question, value)
  152. byte           *address;
  153. char           *question;
  154. word        value;
  155. {
  156.     value = input(question, value);
  157.     PutWord(address, value);
  158.  
  159.     return value;
  160. }
  161.  
  162. byte
  163. SetByte(address, question, value)
  164. byte           *address;
  165. char           *question;
  166. word        value;
  167. {
  168.     value = input(question, value);
  169.     return *address = value;
  170. }
  171.  
  172. byte           *
  173. MaybeWrite(block)
  174. byte           *block;
  175. {
  176.     while (block >= (DiskTrack + TrackSize)) {
  177.     int        t,
  178.             s;
  179.  
  180.     t = Track / nsides;
  181.     s = Track % nsides;
  182.     printf("  Writing cylinder %3d side %d...\r", t, s);
  183.     fflush(stdout);
  184.     TDReq->iotd_Req.io_Command = TD_FORMAT;
  185.     TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
  186.     TDReq->iotd_Req.io_Length = TrackSize;
  187.     TDReq->iotd_Req.io_Offset = TrackSize * Track;
  188.     DoIO(TDReq);
  189.     if (TDReq->iotd_Req.io_Error) {
  190.         printf(" Write error %d on cylinder %d side %d.\n",
  191.            TDReq->iotd_Req.io_Error, t, s);
  192.     }
  193.     TDReq->iotd_Req.io_Command = CMD_UPDATE;
  194.     DoIO(TDReq);
  195.     if (TDReq->iotd_Req.io_Error) {
  196.         printf("Update error %d on cylinder %d side %d.\n",
  197.            TDReq->iotd_Req.io_Error, t, s);
  198.     }
  199.     TDReq->iotd_Req.io_Command = CMD_CLEAR;
  200.     DoIO(TDReq);
  201.  
  202.     printf("  Read\r");
  203.     fflush(stdout);
  204.     TDReq->iotd_Req.io_Command = CMD_READ;
  205.     TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
  206.     TDReq->iotd_Req.io_Length = TrackSize;
  207.     TDReq->iotd_Req.io_Offset = TrackSize * Track;
  208.     DoIO(TDReq);
  209.     if (TDReq->iotd_Req.io_Error) {
  210.         printf("  Read error %d on cylinder %d side %d.\n",
  211.            TDReq->iotd_Req.io_Error, t, s);
  212.     }
  213.     setmem(DiskTrack, (int) TrackSize, 0);
  214.     Track++;
  215.     if ((block -= TrackSize) < DiskTrack)
  216.         block = DiskTrack;
  217.     }
  218.     return block;
  219. }
  220.  
  221. main(argc, argv)
  222. int        argc;
  223. char          **argv;
  224. {
  225.     struct MsgPort *port,
  226.            *CreatePort();
  227.     byte       *diskBlock;
  228.     long        unitNr;
  229.     int         i;
  230.     word        bps = MS_BPS,
  231.             spt = MS_SPT;
  232.     word        res,
  233.             nfats,
  234.             spf,
  235.             nsects,
  236.             ncylinders,
  237.             ndirs,
  238.             wholeDisk,
  239.             endtrack;
  240.  
  241.     if (argc < 2) {
  242.     printf("Usage: %s <unitnr> <device>\n"
  243.            "Formats a messydos volume in any desired shape.\n",
  244.            argv[0]);
  245.     exit(1);
  246.     }
  247.     Enable_Abort = 0;
  248.     unitNr = ntoi(argv[1]);
  249.     if (argc > 2)
  250.     Device = argv[2];
  251.     else
  252.     Device = "messydisk.device";
  253.  
  254.     if (!(port = CreatePort(NULL, 0L))) {
  255.     puts("No memory for replyport");
  256.     goto abort1;
  257.     }
  258.     if (!(TDReq = CreateExtIO(port, (long) sizeof (*TDReq)))) {
  259.     puts("No memory for I/O request");
  260.     goto abort2;
  261.     }
  262.     if (OpenDevice(Device, unitNr, TDReq, 0L)) {
  263.     printf("Cannot OpenDevice %s\n", Device);
  264.     goto abort3;
  265.     }
  266.     bps = input("Bytes per sector", bps);
  267.     spt = input("Sectors per track", spt);
  268.     TrackSize = bps * spt;
  269.     nsides = input("Number of sides", MS_NSIDES);
  270.     Track = input("Starting cylinder", 0);
  271.     Track *= nsides;
  272.     ncylinders = input("Number of cylinders", 80);
  273.     endtrack = Track + nsides * ncylinders;
  274.  
  275.     if ((DiskTrack = AllocMem(TrackSize,
  276.             MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)) == NULL) {
  277.     puts("No memory for track buffer");
  278.     goto abort4;
  279.     }
  280.     CopyMem(BootBlock, DiskTrack, (long) sizeof (BootBlock));
  281.  
  282.     PutWord(DiskTrack + 0x0b, bps);
  283.     SetByte(DiskTrack + 0x0d, "Sectors per cluster", MS_SPC);
  284.     res = SetWord(DiskTrack + 0x0e, "Bootsectors", MS_RES);
  285.     nfats = SetByte(DiskTrack + 0x10, "Number of FAT copies", MS_NFATS);
  286.     ndirs = SetWord(DiskTrack + 0x11, "Root directory entries", MS_NDIRS);
  287.     nsects = SetWord(DiskTrack + 0x13, "Total number of sectors", spt * ncylinders * nsides);
  288.     SetByte(DiskTrack + 0x15, "Media byte", 0xF9);
  289.     spf = SetWord(DiskTrack + 0x16, "Sectors per FAT", MS_SPF);
  290.     PutWord(DiskTrack + 0x18, spt);
  291.     PutWord(DiskTrack + 0x1a, nsides);
  292.     SetWord(DiskTrack + 0x1c, "Number of hidden sectors", 0);
  293.  
  294.     wholeDisk = input("Format whole disk (enter 1)", 0);
  295.     if (input("Are you sure? (enter 42)", 0) != 42)
  296.     goto abort5;
  297.  
  298.     if (Chk_Abort())
  299.     goto abort5;
  300.  
  301.     /* Go to first FAT */
  302.     diskBlock = MaybeWrite(DiskTrack + bps * res);
  303.     for (i = 0; i < nfats; i++) {
  304.     diskBlock[0] = 0xF9;
  305.     diskBlock[1] = 0xFF;
  306.     diskBlock[2] = 0xFF;
  307.     diskBlock = MaybeWrite(diskBlock + bps * spf);  /* Next FAT */
  308.     }
  309.  
  310.     /* Clear entire directory */
  311.     diskBlock = MaybeWrite(diskBlock + ndirs * MS_DIRENTSIZE);
  312.     MaybeWrite(DiskTrack + TrackSize);  /* Force a write */
  313.  
  314.     ncylinders *= nsides;
  315.     if (wholeDisk) {
  316.     while (Track < ncylinders) {
  317.         MaybeWrite(DiskTrack + TrackSize);  /* Write an empty track */
  318.         if (Chk_Abort())
  319.         break;
  320.     }
  321.     }
  322.     TDReq->iotd_Req.io_Command = TD_MOTOR;
  323.     TDReq->iotd_Req.io_Length = 0;
  324.     DoIO(TDReq);
  325.  
  326.     printf("\n\nNow remove the disk from the drive (or use DiskChange).\n");
  327.  
  328. abort5:
  329.     FreeMem(DiskTrack, TrackSize);
  330. abort4:
  331.     CloseDevice(TDReq);
  332. abort3:
  333.     DeleteExtIO(TDReq);
  334. abort2:
  335.     DeletePort(port);
  336. abort1:;
  337.  
  338. }
  339.  
  340. _wb_parse()
  341. {
  342. }
  343.